#include <iostream>
#include <string>
#include <vector>
#include <pthread.h>
#include <unistd.h>

const int threadnum = 5;
class Task
{
public:
    Task(int x, int y) : _datax(x), _datay(y)
    {
    }
    ~Task() {}

    int Excute()
    {
        return _datax + _datay;
    }

private:
    int _datax;
    int _datay;
};

class Threaddata
{
public:
    Threaddata(int x, int y, const std::string &threadname) : _t(x, y), _threadname(threadname) {}
    std::string threadname()
    {
        return _threadname;
    }
    int run()
    {
        return _t.Excute();
    }
    ~Threaddata() {}

private:
    std::string _threadname;
    Task _t;
};

class Result
{
public:
    Result() {}
    ~Result() {}

    void resultset(const std::string &threadname, int result)
    {
        _result = result;
        _threadname = threadname;
    }
    void Print()
    {
        std::cout << _threadname << ":" << _result << std::endl;
    }

private:
    int _result;
    std::string _threadname;
};

void *handlerTask(void *agrs)
{
    Threaddata *td = static_cast<Threaddata *>(agrs);
    std::string name = td->threadname();
    int result = td->run();

    //std::cout << name << " run result: " << result << std::endl;

    sleep(2);
    Result *ret = new Result();
    ret->resultset(name, result);

    delete td;
    return ret;

    // const char *threadname = static_cast<char *>(agrs);
    // while (true)
    // {
    //     std::cout << "i am " << threadname << std::endl;
    //     sleep(1);
    // }
    // delete[] threadname;
    // return nullptr;
}

int main()
{
    std::vector<pthread_t> threads;
    for (int i = 0; i < threadnum; i++)
    {
        // char *threadname = new char[64];
        char threadname[64];
        snprintf(threadname, 64, "Thread-%d", i + 1);

        Threaddata *td = new Threaddata(10, 20, threadname);

        pthread_t tid;
        pthread_create(&tid, nullptr, handlerTask, td);
        threads.push_back(tid);
    }

    void *ret = nullptr;
    std::vector<Result *> result_set;
    for (auto &tid : threads)
    {
        pthread_join(tid, &ret);
        result_set.push_back((Result *)ret);
    }

    for (auto &ret : result_set)
    {
        ret->Print();
        delete ret;
    }
    return 0;
}